package org.ewaf.framework.util;

import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

public class PathBuilder {
	
	private final StringBuffer buffer;
	
	public PathBuilder() {
		this(null);
	}
	
	public PathBuilder(String baseDir) {
		if (baseDir != null) {
			buffer = new StringBuffer(baseDir);
		} else {
			buffer = new StringBuffer();
		}
	}
	
	public PathBuilder appendDatePath(Date date) {
		if (date == null) {
			date = new Date();
		}
		
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int day = cal.get(Calendar.DATE);
		
		buffer.append(StringUtils.leftPad(Integer.toString(year), 4, '0'));
		buffer.append('/');
		buffer.append(StringUtils.leftPad(Integer.toString(month), 2, '0'));
		buffer.append(StringUtils.leftPad(Integer.toString(day), 2, '0'));
		buffer.append('/');
		
		return this;
	}
	
	public PathBuilder appendRandomPath() {
		long seed = System.currentTimeMillis();
		buffer.append(getChar(seed));
		buffer.append(getChar(seed >>>= 5));
		buffer.append('/');
		
		return this;
	}
	
	public PathBuilder appendUniquePath() {
		appendUniqueString();
		buffer.append('/');
		
		return this;
	}
	
	public PathBuilder appendUniqueFileName(String fileName) {
		appendUniqueString();
		
		if (fileName != null) {
			String ext = FilenameUtils.getExtension(fileName);
			if (ext != null && ext.matches("[\\w]+")) {
				buffer.append('.');
				buffer.append(ext);
			}
		}
		
		return this;
	}
	
	private void appendUniqueString() {
		UUID uuid = UUID.randomUUID();
		long least = uuid.getLeastSignificantBits();
		long most = uuid.getMostSignificantBits();
		
		appendLong(buffer, most);
		appendLong(buffer, least);
	}
	
	private static void appendLong(StringBuffer sb, long val) {
        sb.append(getChar(val));
        for(int i = 1; i < 13; i++) {
            sb.append(getChar(val >>>= 5));
        }
    }
	
	private static char getChar(long val) {
        int part = 0x1F & (int)val;
        if (part < 10) {
        	return (char) ('0' + part);
        } else {
        	return (char) ('a' + part - 10);
        }
    }
	
	public String toString() {
		return buffer.toString();
	}
	
}
